

#include "dbfile.h"

u32 crc_tab[256];

void chksum_crc32gentab ()
{
	unsigned long crc, poly;
	int i, j;
	poly = 0xEDB88320L;

	for ( i = 0; i < 256; i++ )
	{
		crc = i;

		for ( j = 8; j > 0; j-- )
		{
			if ( crc & 1 )
			{
				crc = ( crc >> 1 ) ^ poly;
			}
			else
			{
				crc >>= 1;
			}
		}

		crc_tab[i] = crc;
	}
}



/* chksum_crc() -- to a given block, this one calculates the
 *				crc32-checksum until the length is
 *				reached. the crc32-checksum will be
 *				the result.
 */
u32 chksum_crc32 ( unsigned char *block, unsigned int length )
{
	static i32 generate = 0;

	if ( !generate )
	{
		chksum_crc32gentab();
		generate = 1;
	}

	register unsigned long crc;
	unsigned long i;
	crc = 0xFFFFFFFF;

	for ( i = 0; i < length; i++ )
	{
		crc = ( ( crc >> 8 ) & 0x00FFFFFF ) ^ crc_tab[ ( crc ^ *block++ ) & 0xFF];
	}

	return ( crc ^ 0xFFFFFFFF );
}

/* chksum_crc32gentab() --      to a global crc_tab[256], this one will
 *				calculate the crcTable for crc32-checksums.
 *				it is generated to the polynom [..]
 */



u32 dbf_header::crc()
{
	u32 crc;
	dbf_header h = *this;
	h.crc_checksum = 0;
	crc = chksum_crc32 ( ( u8* ) &h, sizeof ( dbf_header ) );
	return crc;
}

u32 dbf_bat::crc()
{
	u32 crc;
	dbf_bat h = *this;
	h.bat_crc = 0;
	crc = chksum_crc32 ( ( u8* ) &h, sizeof ( dbf_bat ) );
	return crc;
}

u32 dbf_block::crc()
{
	u32 crc;
	dbf_block h = *this;
	h.bl_crc = 0;
	crc = chksum_crc32 ( ( u8* ) &h, sizeof ( dbf_block ) );
	return crc;
}

u32 dataCRC(void *data, u32 len)
{
    return chksum_crc32((u8*)data,len);
}
